package com.binarysoft.cmdhandler.common.service;

import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import common.framework.command.handler.AbstractCommandHandler;
import common.framework.command.helper.CommandHelper;
import common.framework.command.server.Terminal;
import common.framework.dsb.annotation.DSBCmd;
import common.framework.dsb.client.DefaultServiceFactory;
import common.framework.dsb.client.ServiceFactory;
import common.framework.dsb.service.ServiceDescriptor;
import common.framework.md5.MD5;

@DSBCmd("service")
public class ShowServiceCmdHandler extends AbstractCommandHandler {

	public void close() {

	}

	public void handle(String args, Terminal terminal) throws Exception {
		terminal.println("");
		StringTokenizer stier = new StringTokenizer(args);
		int count = stier.countTokens();
		if (count < 2) {
			terminal.println(" Usage:");
			terminal.println(" service ls                      -- list all services");
			terminal.println(" service name     <ServiceName>  -- list details of a service specified by <ServiceName>");
			terminal.println(" service start    <ServiceName>  -- start a service specified by <ServiceName>");
			terminal.println(" service close    <ServiceName>  -- close a service specified by <ServiceName>");
			terminal.println(" service refresh  <ServiceName>  -- refresh a service specified by <ServiceName>");
			terminal.println("");
			return;
		}
		stier.nextToken();
		String cmd = stier.nextToken();
		if ("ls".equalsIgnoreCase(cmd) && count == 2) {
			listService(terminal);
		} else if ("name".equalsIgnoreCase(cmd) && count == 3) {
			String serviceName = stier.nextToken();
			listService(serviceName, terminal);
		} else if ("start".equalsIgnoreCase(cmd) && count == 3) {
			String serviceName = stier.nextToken();
			startService(serviceName, terminal);
		} else if ("close".equalsIgnoreCase(cmd) && count == 3) {
			String serviceName = stier.nextToken();
			closeService(serviceName, terminal);
		} else if ("refresh".equalsIgnoreCase(cmd) && count == 3) {
			String serviceName = stier.nextToken();
			refreshService(serviceName, terminal);
		} else {
			terminal.println(" Usage:");
			terminal.println(" service ls                      -- list all services");
			terminal.println(" service name     <ServiceName>  -- list details of a service specified by <ServiceName>");
			terminal.println(" service start    <ServiceName>  -- start a service specified by <ServiceName>");
			terminal.println(" service close    <ServiceName>  -- close a service specified by <ServiceName>");
			terminal.println(" service refresh  <ServiceName>  -- refresh a service specified by <ServiceName>");
		}
		terminal.println("");
	}

	private void listService(Terminal terminal) throws Exception {
		ServiceFactory serviceFactory = new DefaultServiceFactory();
		String[] tableHAD = { "Service name", "Status", "Startup" };
		String[] tableGAP = { "------------", "------", "-------" };
		int[] format = { 40, 10, 10 };
		terminal.println(CommandHelper.format(tableHAD, format));
		terminal.println(CommandHelper.format(tableGAP, format));
		List<String> startedServices = serviceFactory.listStartedService();
		List<ServiceDescriptor> beans = serviceFactory.list();
		Iterator<ServiceDescriptor> iter = beans.iterator();
		while (iter.hasNext()) {
			ServiceDescriptor bd = iter.next();
			Object[] row = { bd.serviceName, startedServices.contains(bd.serviceName) ? "on" : "off", bd.startup };
			terminal.println(CommandHelper.format(row, format));
		}
		terminal.println("");
		terminal.println("Total: " + beans.size() + " service(s).");
		terminal.println("");
	}

	private void listService(String serviceName, Terminal terminal) throws Exception {
		String[] tableHAD = { "Service name", "Class" };
		String[] tableGAP = { "------------", "-----" };
		int[] format = { 40, 30 };
		terminal.println(CommandHelper.format(tableHAD, format));
		terminal.println(CommandHelper.format(tableGAP, format));
		ServiceFactory serviceFactory = new DefaultServiceFactory();
		List<ServiceDescriptor> bdts = serviceFactory.list();
		for (ServiceDescriptor bdt : bdts) {
			if (bdt.serviceName.equals(serviceName)) {
				String className = bdt.interfaceClassName;
				terminal.println(CommandHelper.format(new Object[] { serviceName, className }, format));
				terminal.println("");
				Class<?> beanClass = Class.forName(className);
				Method[] methods = beanClass.getDeclaredMethods();
				if (methods.length > 0) {
					terminal.println("--method signatures--");
				}
				for (Method m : methods) {
					Class<?>[] types = m.getParameterTypes();
					terminal.println(MD5.methodSignature(m.getName(), types));
				}
				terminal.println("");
			}
		}// for
	}

	private void startService(String serviceName, Terminal terminal) throws Exception {
		ServiceFactory serviceFactory = new DefaultServiceFactory();
		boolean result = serviceFactory.startService(serviceName);
		if (result) {
			terminal.println("service [" + serviceName + "] started !");
		} else {
			terminal.println("service [" + serviceName + "] failed to start !");
		}
	}

	private void closeService(String serviceName, Terminal terminal) throws Exception {
		ServiceFactory serviceFactory = new DefaultServiceFactory();
		boolean result = serviceFactory.closeService(serviceName);
		if (result) {
			terminal.println("service [" + serviceName + "] closed !");
		} else {
			terminal.println("service [" + serviceName + "] failed to close !");
		}
	}

	private void refreshService(String serviceName, Terminal terminal) throws Exception {
		ServiceFactory serviceFactory = new DefaultServiceFactory();
		boolean result = serviceFactory.refreshService(serviceName);
		if (result) {
			terminal.println("service [" + serviceName + "] refreshed !");
		} else {
			terminal.println("service [" + serviceName + "] failed to refresh !");
		}
	}
}
